trait Speak {
    // 特质里的常量，默认静态声明周期，贯穿整个程序
    const NAME: &'static str = "Speak";

    // 关联函数，必须实现
    fn hi();

    // 关联函数，默认实现
    fn hello() {
        println!("Hello");
    }

    // 方法，默认实现，获取使用权
    fn say_name(&self) {
        println!("Say name");
    }

    // 方法，必须实现，获取使用权
    fn say_age(&self);

    // 方法，必须实现，获取使用权，带返回值
    fn again(&self) -> String;

    // 方法，必须实现，获取所有权（因为所有权都给了，在类型实现上可以兼容mut self模式）
    fn reset(self) -> Self;
}

#[derive(Debug)]
struct Person {
    name: String,
    age: u8,
}

impl Speak for Person {
    // 必须实现的关联函数，不实现编译会报错
    fn hi() {
        println!("Hi, I'm a person")
    }

    // 默认实现的关联函数，可以不实现，类型可以照常调用
    // fn hello() {
    //     println!("Hello, I'm a person")
    // }

    // 必须实现的方法，不实现编译会报错
    fn say_age(&self) {
        println!("My name is {}", self.age);
    }

    // 默认实现的方法，可以不实现，类型可以照常调用
    // 只要在类型实现特质里，对特质的方法进行了声明，就会覆盖特质里的方法，无关静态或实例
    fn say_name(&self) {
        // println!("My name is {}", self.name);
    }

    // 必须实现的方法，必须有返回值，特质里同名方法必须给出返回值类型，上下需要保持一致
    fn again(&self) -> String {
        String::from("pardon")
    }

    // 必须实现的方法，获取所有权
    fn reset(mut self) -> Self {
        self.name = String::default();
        self.age = u8::default();
        self

        // 在Person结构体，实现了Default特质，可以用下面这种写法返回默认值
        // Person::default()
    }
}

fn main() {
    // 特质静态方法的调用
    Person::hi();
    // 默认实现的方法，可以不实现，类型可以照常调用
    Person::hello();

    let p = Person {
        name: String::from("daniel"),
        age: 25,
    };

    // 特质实例方法的调用
    p.say_name();
    p.say_age();
    p.again();

    let p = p.reset();
    println!("{p:?}")
}
